import time
import json

from flask import render_template, jsonify, request, url_for, redirect
from flask.app import Response
from flask.blueprints import Blueprint

from core.redis_server import RedisServer


v1_bp_api = Blueprint('api', __name__, url_prefix='/api/v1/proxy')
server = RedisServer()
URLNotFoundError = '''
        请求缺少url参数
        如果您使用GET请求，示例：http(s)://host:port/api/v1/proxy?url=您需要爬取网站的URL。
        如果您使用POST请求，请求体示例： {"url": "您需要请求网站的URL"}。
        '''


@v1_bp_api.route('/', methods=['GET', 'POST'], strict_slashes=False, endpoint='index')
def index():
    result = {'code': 1000, 'data': None, 'error': None}
    if request.method == "GET":
        params = request.args.to_dict()
    else:
        if request.headers.get('Content-Type') == 'application/json':
            params = json.loads(request.data.decode())
        else:
            params = request.form.to_dict()
    url = params.get('url', None) or params.get('URL', None)
    # 使用restful规范
    if url is None:
        result['data'] = server.get_one_proxy_from_interface()
        return result
    proxy = server.get_proxy(url)
    if 'ERROR' in proxy:
        result['code'] = 1001
        result['error'] = proxy
        return result
    else:
        result['data'] = proxy
        return result


@v1_bp_api.route('/all',  methods=['GET', 'POST'], strict_slashes=False, endpoint='all')
def one_source_all_proxy():
    data = {}
    result = {'code': 1000, 'data': None, 'error': None}
    if request.method == 'GET':
        params = request.args.to_dict()
    else:
        if request.headers.get('Content-Type') == 'application/json':
            params = json.loads(request.data.decode())
        else:
            params = request.form.to_dict()
    url = params.get('url', None) or params.get('URL', None)
    count = params.get('count', None) or params.get('COUNT', None)
    try:
        count = int(count)
    except Exception:
        count = None
    if url is None:
        source_list = server.get_source_list()
        for source in source_list:
            proxy = server.get_all_proxy_from_source(source, True)
            if 'ERROR' in proxy:
                result['code'] = 1001
                result['error'] = proxy
                return result
            data[source] = proxy
        result['data'] = {'sourceNumber': len(source_list), 'result': data}
        return jsonify(result)
    else:
        source_list = server.get_source_list()
        print(source_list)
        all_proxy = server.get_all_proxy_from_source(url, True)
        if 'ERROR' in all_proxy:
            result['code'] = 1001
            result['error'] = all_proxy
            return result
        if count:
            all_proxy = all_proxy[:count]
        url = server.handle_key(url)
        if not server._is_host(url):
            url = server._get_netloc(server.handle_key(url))
        result['data'] = {'host': url, 'number': len(all_proxy), 'result': all_proxy}
        return jsonify(result)


@v1_bp_api.app_errorhandler(404)
def handler404(message):
    result = {'code': 1002, 'data': None, 'error': '404 Not Found'}
    return jsonify(result)


@v1_bp_api.app_template_global()
def length(iter_):
    return len(iter_)


@v1_bp_api.app_template_global()
def integer(number):
    return int(number)


v1_bp_manage = Blueprint('manage', __name__, url_prefix='/')


@v1_bp_manage.route('/', methods=['GET'], strict_slashes=False, endpoint='index')
def index():
    all_source = server.get_source_list()
    line, div = divmod(len(all_source), 5)
    return render_template('index.html', all_source=all_source, line=line, div=div, num=5)


@v1_bp_manage.route('/info', methods=['GET'], strict_slashes=False, endpoint='info')
def info():
    params = request.args.to_dict()
    url = params.get('url')
    if url:
        if not server._is_host(url):
            url = server._get_netloc(url)
        all_proxy = server.get_all_proxy_from_source(url, True)
        have_expiration_proxy_list = [proxy for proxy in all_proxy if proxy.get('expiration', None)]
        have_expiration_proxy_list = sorted(have_expiration_proxy_list, key=lambda proxy: time.mktime(time.strptime(proxy['expiration'], '%Y-%m-%d %H:%M:%S')))
        not_have_expiration_proxy_list = [proxy for proxy in all_proxy if not proxy.get('expiration', None)]
        have_expiration_proxy_list.extend(not_have_expiration_proxy_list)
        return render_template('info.html', all_proxy=have_expiration_proxy_list, netloc=url)
    else:
        return Response('无URL参数')
        # return redirect(url_for('api.all'))


@v1_bp_manage.route('/proxy_delete', methods=['GET'], strict_slashes=False, endpoint='proxy_delete')
def proxy_delete():
    params = request.args.to_dict()
    proxy = params.get('proxy')
    netloc = params.get('netloc')
    all_info = server.get_all_proxy_from_source(netloc)
    for info in all_info:
        if info['proxy'] == proxy:
            server.delete_one_proxy_from_source(netloc, info)
    return {'code': 1000, 'data': None, 'error': None}


@v1_bp_manage.route('/netloc_delete', methods=['GET'], strict_slashes=False, endpoint='netloc_delete')
def netloc_delete():
    params = request.args.to_dict()
    netloc = params.get('netloc')
    server.delete_source(netloc)
    return {'code': 1000, 'data': None, 'error': None}


@v1_bp_manage.app_template_global()
def url(bp_name, endpoint, **kwargs):
    return url_for('{}.{}'.format(bp_name, endpoint), **kwargs)




